package hk.polyu;

import java.io.*;
import java.util.*;
import java.util.Map.Entry;


/**
 * This class store the index for all documents.
 * @author hezongjian
 *
 */
public class DocumentIndex implements Index{
		
	/**
	 * Constant string storing file name
	 */
	public static final String FILE_NAME = "document.txt"; 
	
	/**
	 * Hash map storing all the documents.
	 */
	HashMap<Integer, BasicDocumentInfo> mDocs;
	
	/**
	 * Storing all token count.
	 */
	int	mCollectionLength;
	
	/**
	 * <code>
	    # documentCount, collectionLength
		3, 18
		# documentID, documentLength, documentPath
		0, 6, a.txt
		1, 7, b.txt
		2, 5, c.txt
	 * </code>
	 */
	@Override
	public void save(String path) throws IOException {
		if (! path.endsWith(File.separator))
			path += File.separator;
		String fullName = path + DocumentIndex.FILE_NAME;
		
		PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(fullName)));
		
		out.println("# documentCount, collectionLength");
		out.printf("%d,  %d\r\n", this.mDocs.keySet().size(), this.mCollectionLength);
		
		out.println("# documentID, documentLength, documentPath");
		for (BasicDocumentInfo d : this.mDocs.values()) {
			out.printf("%d, %d, %s\r\n",
					d.mID,
					d.mLength,
					d.mPath);
		}
		
		out.close();
	}

	@Override
	public void load(String path) throws IOException {
		String line;
		BufferedReader input =  new BufferedReader(new FileReader(path));
		
		this.mDocs = new HashMap<Integer, BasicDocumentInfo>();
		
		// read header information.
		while ((line = input.readLine()) != null) {
			if (! line.startsWith("#"))
				break;
		}
		String [] headers = line.split(",");
		this.mCollectionLength = Integer.parseInt(headers[1].trim());
		int docCount = Integer.parseInt(headers[0].trim());
		
		// read the rest
		while ((line = input.readLine()) != null) {
			if ( line.startsWith("#") )
				continue;
			// Separate with comma
			String [] elems = line.split(",");
			int docID = Integer.parseInt(elems[0].trim());
			int docLen = Integer.parseInt(elems[1].trim());
			String docPath = elems[2].trim();
			
			BasicDocumentInfo bdi = new BasicDocumentInfo();
			bdi.mID = docID;
			bdi.mLength = docLen;
			bdi.mPath = docPath;
			File tf = new File(docPath);
			bdi.mName = tf.getName();
			
			this.mDocs.put(docID, bdi);
	    }
		
		// Assume the length is correct.
		if (docCount != this.mDocs.size())
			System.out.println("Something Wrong");
		
		input.close();
		
	}

	@Override
	public void generate(CollectionInfo ci) {
		
		mDocs = new HashMap<Integer, BasicDocumentInfo>();
		
		this.mCollectionLength = ci.getCollectionLength();
		
		Iterator<Entry<Integer, DocumentInfo>> it = ci.mDocs.entrySet().iterator();
		
		while(it.hasNext()) {
			Entry<Integer, DocumentInfo> pairs = it.next();
			DocumentInfo di = pairs.getValue();
			BasicDocumentInfo bdi = new BasicDocumentInfo();
			bdi.mID = di.mID;
			bdi.mLength = di.mLength;
			bdi.mName = di.mName;
			bdi.mPath =di.mPath;
			// add to hash
			this.mDocs.put(pairs.getKey(), bdi);
		}
	}

	/**
	 * Return the total number of documents in the index file.
	 * @return the number of document.
	 */
	public int getDocumentCount() {
		return this.mDocs.keySet().size();
	}
	

}
